import {
  Injectable,
  Inject,
  BadRequestException,
  ConflictException,
} from '@nestjs/common';
import { Schema, Document } from 'mongoose';
import * as md5 from 'md5';

import { UserModel } from '@server/models';

import { AuthService } from '@server/auth';

import { BaseResponse } from '@server/basic-dto';

import { CreateUserOrUserLoginDto, UserLoginResponse } from './dto';
import { USER_EXIST, USERNAME_PASSWORD_ERROR } from './error';

@Injectable()
export default class BlogService {
  constructor(
    private readonly authService: AuthService,
    @Inject('USER_MODEL') private readonly userModel: typeof UserModel,
  ) {}

  async create(createUser: CreateUserOrUserLoginDto): Promise<BaseResponse> {
    const count: number = await this.userModel.countDocuments({
      username: createUser.username,
    });

    if (count > 0) {
      throw new ConflictException(USER_EXIST);
    }

    await this.userModel.create({
      username: createUser.username,
      password: md5(createUser.password),
    });

    return {
      code: 0,
      message: '',
    };
  }

  async login(
    createUser: CreateUserOrUserLoginDto,
  ): Promise<UserLoginResponse> {
    const user: any = await this.userModel.findOneAndUpdate(
      {
        username: createUser.username,
        password: md5(createUser.password),
      },
      {
        lastLogin: Date.now(),
      },
    );

    if (!user) {
      throw new BadRequestException(USERNAME_PASSWORD_ERROR);
    }

    return {
      code: 0,
      message: '',
      data: {
        username: user.username,
        token: this.authService.signIn(user.id, user.username, user.password),
      },
    };
  }

  async logout(token: string): Promise<BaseResponse> {
    await this.authService.signOut(token);

    return {
      code: 0,
      message: '',
    };
  }
}
